package com.papper.mng.controller.sys;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.papper.common.bean.sys.SysModel;
import com.papper.common.bean.sys.SysResource;
import com.papper.common.bean.sys.SysSystem;
import com.papper.common.enums.DataStatusEnum;
import com.papper.common.exception.ServiceException;
import com.papper.common.service.sys.SysModelService;
import com.papper.common.service.sys.SysResourceService;
import com.papper.common.service.sys.SysSystemService;
import com.papper.common.utils.tool.StringTool;
import com.papper.mng.controller.BaseAction;
import com.papper.mng.domain.DwzResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

/**
 * 系统资源
 */
@Controller
@RequestMapping("/sys/resource")
public class SysResourceAction extends BaseAction {
    @Autowired
    SysSystemService   sysSystemService;
    @Autowired
    SysModelService    sysModelService;
    @Autowired
    SysResourceService sysResourceService;

    /**
     * 系统模块首页
     *
     * @return
     */
    @RequestMapping(value = "")
    public String execute(HttpServletRequest _request, Model model, Long sid, Long mid, String fid) {
        // 所属系统
        List<SysSystem> systems = sysSystemService.findAll();
        model.addAttribute("systems", systems);
        SysSystem sysSystem = sysSystemService.findById(sid);
        if (sysSystem == null && systems.size() > 0) {
            sysSystem = systems.get(0);
        }
        if (sysSystem == null) {
            return render("sys/resource/index");
        }
        // 所属模块
        model.addAttribute("sysSystem", sysSystem);
        model.addAttribute("sid", sysSystem.getId());
        List<SysModel> sysModels = sysModelService.findBySystemId(sysSystem.getId());
        if (sysModels == null) {
            return render("sys/resource/index");
        }
        SysModel sysModel = sysModelService.findById(mid);
        if (sysModel == null && sysModels.size() > 0) {
            sysModel = sysModels.get(0);
        } else if (sysModel != null && sysModel.getSystemId() != sysSystem.getId().intValue()) {
            sysModel = sysModels.get(0);
        }
        if (sysModel == null) {
            return render("sys/resource/index");
        }
        // 所属资源
        model.addAttribute("sysModel", sysModel);
        model.addAttribute("sysModels", sysModels);
        model.addAttribute("mid", sysModel.getId());
        model.addAttribute("fid", fid);
        List<SysResource> sysResources = sysResourceService.findByMid(sysModel.getId());
        sysResourceService.matchLevel(sysResources);
        if (fid != null) {
            SysResource sysResource = sysResourceService.findById(fid);
            if (sysResource != null && sysResource.getModelId().intValue() == sysModel.getId().intValue()) {
                List<SysResource> filters = Lists.newArrayList();
                for (SysResource sr : sysResources) {
                    if (sr.getUpFamily().startsWith(sysResource.getUpFamily())) {
                        filters.add(sr);
                    }
                }
                sysResources = filters;
            }
        }
        model.addAttribute("sysResources", sysResourceService.treeChildList(sysResources));
        return render("sys/resource/index");
    }

    /**
     * 系统资源_新增
     *
     * @param _response
     * @throws IOException
     */
    @GetMapping(value = "/add")
    public String add_get (HttpServletResponse _response, Model model, Long sid, Long mid, Long pid) throws IOException {
        model.addAttribute("sid", sid);
        model.addAttribute("mid", mid);
        model.addAttribute("pid", pid);
        SysSystem sysSystem = sysSystemService.findById(sid);
        model.addAttribute("sysSystem", sysSystem);
        SysModel sysModel = sysModelService.findById(mid);
        model.addAttribute("sysModel", sysModel);
        SysResource sysResource = sysResourceService.findById(pid);
        model.addAttribute("resName", sysResource == null ? "顶级资源" : sysResource.getResName());
        return render("sys/resource/add");
    }

    @PostMapping(value = "/add")
    @ResponseBody
    public DwzResponse add_post(HttpServletRequest _request, HttpServletResponse _response, SysResource sysResource) {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (sysResource == null) {
            return new DwzResponse("300", "参数异常！");
        }
        sysResource.setUpFamily("");
        sysResource.setUpChild(0);
        sysResource.setCreateTime(new Date());
        sysResource.setModifyTime(new Date());
        try {
            sysResource.setDataStatus(DataStatusEnum.OPEN.getCode());
            sysResourceService.save(sysResource);
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "系统错误,请稍候再试!!![" + e.getMessage() + "]");
        }
        // 维护组树信息
        sysResourceService.matchFamily(sysResource);
        sysResourceService.matchChild(sysResourceService.findById(sysResource.getUpId()));
        return new DwzResponse("200", "系统资源新增成功!!!");
    }

    /**
     * 系统资源_更新
     *
     * @param _response
     * @throws IOException
     */
    @GetMapping(value = "/edit")
    public String edit_get (HttpServletResponse _response, Model model, Long id) throws IOException {
        SysResource sysResource = sysResourceService.findById(id);
        model.addAttribute("entity", sysResource);
        SysResource parent = sysResourceService.findById(sysResource.getUpId());
        model.addAttribute("resName", parent == null ? "顶级资源" : parent.getResName());
        SysSystem sysSystem = sysSystemService.findById(sysResource.getSystemId());
        model.addAttribute("sysSystem", sysSystem);
        SysModel sysModel = sysModelService.findById(sysResource.getModelId());
        model.addAttribute("sysModel", sysModel);

        return render("sys/resource/edit");
    }

    @PostMapping(value = "/edit")
    @ResponseBody
    public DwzResponse edit_post(HttpServletRequest _request, HttpServletResponse _response, SysResource sysResource) throws IOException {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (sysResource == null || sysResource.getId() == null) {
            return new DwzResponse("300", "参数异常！");
        }
        sysResource.setModifyTime(new Date());
        try {
            sysResourceService.update(sysResource);
            return new DwzResponse("200", "系统资源修改成功!!!");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "系统错误,请稍候再试!!![" + e.getMessage() + "]");
        }
    }

    /**
     * 系统资源_更新
     *
     * @param _response
     * @throws IOException
     */
    @GetMapping(value = "/match")
    public String match_get(HttpServletRequest _request, HttpServletResponse _response, Model model, Long id) {
        SysResource matchSysResource = sysResourceService.findById(id);
        model.addAttribute("entity", matchSysResource);
        SysResource parent = sysResourceService.findById(matchSysResource.getUpId());
        model.addAttribute("resName", parent == null ? "顶级资源" : parent.getResName());
        SysSystem sysSystem = sysSystemService.findById(matchSysResource.getSystemId());
        model.addAttribute("sysSystem", sysSystem);
        SysModel sysModel = sysModelService.findById(matchSysResource.getModelId());
        model.addAttribute("sysModel", sysModel);
        //匹配地址一览
        TreeSet<String> reqList = Sets.newTreeSet();
        Example         example = new Example(SysResource.class);
        example.createCriteria().andEqualTo("systemId", sysSystem.getId());
        List<SysResource> sysResourceList = sysResourceService.find(example);
        // 获取请求地址一览
        WebApplicationContext                  wac  = (WebApplicationContext) _request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);//获取上下文对象
        RequestMappingHandlerMapping           rmhp = wac.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map  = rmhp.getHandlerMethods();
        for (Iterator<RequestMappingInfo> iterator = map.keySet().iterator(); iterator.hasNext(); ) {
            RequestMappingInfo info = iterator.next();
            if (info == null) {
                continue;
            }
            if (info.getPatternsCondition() == null) {
                continue;
            }
            if (info.getPatternsCondition().getPatterns() == null) {
                continue;
            }
            if (info.getPatternsCondition().getPatterns().size() <= 0) {
                continue;
            }
            String compUrl = StringTool.nullToEmpty(info.getPatternsCondition().getPatterns().toArray()[0]);
            if (StringUtil.isEmpty(compUrl)) {
                continue;
            }
            compUrl = compUrl.substring(1);
            SysResource sysResource = null;
            if (sysResourceList != null) {
                for (SysResource sysResource1 : sysResourceList) {
                    if (sysResource1.getResUrl().startsWith(compUrl + ".")) {
                        sysResource = sysResource1;
                        break;
                    }
                }
            }
            if (sysResource == null && !compUrl.startsWith("sys") && !compUrl.startsWith("test")) {
                reqList.add(compUrl);
            }
        }
        model.addAttribute("reqList", reqList);
        return render("sys/resource/match");
    }

    @PostMapping(value = "/match")
    @ResponseBody
    public DwzResponse match_post(HttpServletRequest _request, HttpServletResponse _response, SysResource sysResource, String url) {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (sysResource == null || sysResource.getId() == null) {
            return new DwzResponse("300", "参数异常！");
        }
        sysResource.setResUrl(url + "");
        sysResource.setResLimit(StringTool.getCamelCaseString(url, true));
        sysResource.setModifyTime(new Date());
        try {
            sysResourceService.update(sysResource);
            return new DwzResponse("200", "系统资源修改成功!!!");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "系统错误,请稍候再试!!![" + e.getMessage() + "]");
        }
    }

    /**
     * 系统资源_删除
     *
     * @param _response
     * @param id
     * @throws IOException
     */
    @PostMapping(value = "/del")
    @ResponseBody
    public DwzResponse del(HttpServletRequest _request, HttpServletResponse _response, Long id) throws IOException {
        try {
            checkSuperCert(_request);
        } catch (ServiceException e) {
            return new DwzResponse("300", e.getMessage());
        }
        if (id == null || id.intValue() <= 0) {
            return new DwzResponse("300", "参数异常！");
        }
        SysResource old = sysResourceService.findById(id);
        if (old == null) {
            return new DwzResponse("300", "数据信息异常！");
        }
        // 删除系统
        try {
            sysResourceService.deleteById(old.getId());
            // 删除子资源
            sysResourceService.deleteByChild(old);
            // 维护父资源信息
            sysResourceService.matchChild(sysResourceService.findById(old.getUpId()));
            return new DwzResponse("200", "系统删除成功!!!");
        } catch (Exception e) {
            e.printStackTrace();
            return new DwzResponse("300", "系统错误,请稍候再试!!![" + e.getMessage() + "]");
        }
    }

    /**
     * 系统资源_详情
     *
     * @return
     */
    @RequestMapping(value = "/detail")
    public String detail (HttpServletResponse _response, Model model, Long id) throws IOException {
        SysResource sysResource = sysResourceService.findById(id);
        model.addAttribute("entity", sysResource);
        model.addAttribute("sysSystem", sysSystemService.findById(sysResource.getSystemId()));
        model.addAttribute("sysModel", sysModelService.findById(sysResource.getModelId()));
        SysResource upResource = sysResourceService.findById(sysResource.getUpId());
        model.addAttribute("resName", upResource == null ? "顶级资源" : upResource.getResName());
        return render("sys/resource/detail");
    }
}